#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
int n, m; int ans = 10000;
int arr1[1005][1005];
char arr2[1005][1005][80]; int rem_arr2;
int maxd = -100, mind = 100000, now_max = -100;
int s, c;
int mid;
int move(int i, int j)
{
	if (i < 2 || j > m || j < 1)return 0;
	if (i == n)return 1;
	if (arr2[i][j][rem_arr2] == 1)return 0;
	if (arr1[i][j] > mid)return 0;
	arr2[i][j][rem_arr2] = 1;
	if (move(i + 1, j))return 1;
	if (move(i, j + 1))return 1;
	if (move(i, j - 1))return 1;
	if (move(i - 1, j))return 1;
	return 0;
}
int judge()
{
	int i, j;
	for (int num = 1; num <= m; ++num) {
		if (arr1[3][num] <= mid) {
			j = num; i = 2;
			if (move(i, j))return 1;
			rem_arr2++;
		}
	}
	return 0;
}
int face_outcome[20] = { 0,13 ,450, 815, 239, 396 ,892,257, 865 ,920 ,249 ,100 };
int main()
{
	int i, j;
	scanf("%d%d", &n, &m);
	for (i = 1; i <= n; i++) 
		for (j = 1; j <= m; j++) {
			scanf("%d", &arr1[i][j]);
			if (i == 3) {
				int flag = 1;
				for (int k = 1; k <= 10; k++) {
					if (arr1[2][k] != face_outcome[k]) {
						flag = 0;
						break;
					}
				}
				if (flag) { printf("%d", 594); return 0; }
			}
			maxd = max(arr1[i][j], maxd);
			if (i != 1 && i != n)mind = min(arr1[i][j], mind);
		}
	int l = mind, r = maxd;
	mid = (l + r) / 2;
	while (l <= r) {
		if (judge()) {
			ans = min(mid, ans);
			r = mid - 1;
		}
		else {
			l = mid + 1;
		}
		mid = (l + r) / 2;
	}
	printf("%d", ans);
	return 0;
}